package com.alibaba.citrus.cr.unified.inventory.utils;

import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByIdsRequest;
import com.epoch.app.bcorder.model.dto.QueryCargoZoneByIdRequest;
import com.epoch.app.bcorder.model.dto.QueryCargoZoneByIdResponse;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.crplatformenhance.credit.model.Credit;
import com.epoch.app.crplatformenhance.credit.service.CreditService;
import com.epoch.app.crplatformenhance.domain.customeraddress.dto.BatchQueryByIdsRequest;
import com.epoch.app.crplatformenhance.domain.customeraddress.model.CustomerAddress;
import com.epoch.app.crplatformenhance.domain.customeraddress.service.CustomerAddressService;
import com.epoch.app.crplatformenhance.model.dto.BatchQueryCustomersRequest;
import com.epoch.app.crplatformenhance.model.dto.CreditLoadListRequest;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.epoch.app.crunifiedinventory.dto.response.AllocateApplyOrderDetailDTO;
import com.epoch.app.crunifiedinventory.dto.response.AllocateApplyOrderGoodsDetailDTO;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderGetCustomerResponse;
import com.epoch.app.crunifiedinventory.model.dto.CustomerAndAddressInfo;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateApplyOrderStatusEnum;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.epoch.app.crunifiedinventory.sdo.enums.ReasonForRejectionEnum;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 调拨预报单工具类
 */
@Component
public class AllocateApplyOrdeUtils {
    private static Log log = Log.getLogger(AllocateApplyOrdeUtils.class);


    private static final String SAPINTERNAL_SALES_BP_CODE = "sapInternalSalesBPCode";
    private static final String SAP_INTERNAL_DELIVERY_BP_CODE = "sapInternalDeliveryBPCode";
    private static final String SAP_SALE_BP_CODE = "sapSaleBPCode";
    private static final String SAP_DELIVERY_BP_CODE = "sapDeliveryBPCode";
    private static final String NAME = "name";
    private static final String ID = "id";
    private static final String SAP_FACTORY_CODE = "sapFactoryCode";
    private static final String WAREHOUSE_CODE = "warehouseCode";
    private static final String RESULT = "result";
    private static final String ADDRESS = "address";
    private static final String ADDRESS_NAME = "addressName";
    private static final String CUSTOMER_CODE = "customerCode";
    private static final String CUSTOMER_NAME = "customerName";
    private static final String REAL_NAME = "realName";
    private static final String ORGANIZATION_SDO = "organizationSDO";
    private static final String YES_NAME = "是";
    private static final String NO_NAME = "否";
    private static final String ZERO_STRING = "0";
    private static final String NULL_STRING = "";


    private static UnifiedInventoryService unifiedInventoryService;
    private static CrPlatformEnhanceService otsPlatformEnhanceService;
    private static BaseDataService baseDataService;
    private static CustomerAddressService customerAddressService;
    private static CreditService creditService;


    public static AllocateApplyOrderDetailDTO optimizationAllocateApplyOrderDetail(AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO) {

        //通过收货仓id查找逻辑仓库中所需要的数据
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getReceiveWarehouseId())) {
            QueryCargoZoneByIdRequest queryCargoZoneByIdRequest = new QueryCargoZoneByIdRequest();
            queryCargoZoneByIdRequest.setCargoZoneIdList(Lists.newArrayList(allocateApplyOrderDetailDTO.getReceiveWarehouseId()));
            QueryCargoZoneByIdResponse queryCargoZoneByIdResponse = unifiedInventoryService.queryCargoZoneById(queryCargoZoneByIdRequest);
            if (Objects.nonNull(queryCargoZoneByIdResponse) && CollectionUtils.isNotEmpty(queryCargoZoneByIdResponse.getResult())) {
                Map<String, String> result = (Map<String, String>) queryCargoZoneByIdResponse.getResult().get(0);
                //非工厂直发单
                if (!Objects.equals(allocateApplyOrderDetailDTO.getIsDTC(),Boolean.TRUE)){
                    //总部内部售达方编号
                    allocateApplyOrderDetailDTO.setSapInternalSalesBPCode(result.get(SAPINTERNAL_SALES_BP_CODE));
                    //总部内部送达方编号
                    allocateApplyOrderDetailDTO.setSapInternalDeliveryBPCode(result.get(SAP_INTERNAL_DELIVERY_BP_CODE));
                    //总部售达方编号
                    allocateApplyOrderDetailDTO.setSapSalesBPCode(result.get(SAP_SALE_BP_CODE));
                    //总部送达方编号
                    allocateApplyOrderDetailDTO.setSapDeliveryBPCode(result.get(SAP_DELIVERY_BP_CODE));
                }
                //收货仓名称
                allocateApplyOrderDetailDTO.setReceiveWarehouseName(result.get(NAME));
                allocateApplyOrderDetailDTO.setReceiveWarehouseCode(result.get("code"));
            }
        }

        //通过发货仓id查找逻辑仓库中所需要的数据
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getShipWarehouseId())) {
            QueryCargoZoneByIdRequest queryCargoZoneByIdRequest = new QueryCargoZoneByIdRequest();
            queryCargoZoneByIdRequest.setCargoZoneIdList(Lists.newArrayList(allocateApplyOrderDetailDTO.getShipWarehouseId()));
            QueryCargoZoneByIdResponse queryCargoZoneByIdResponse = unifiedInventoryService.queryCargoZoneById(queryCargoZoneByIdRequest);
            if (Objects.nonNull(queryCargoZoneByIdResponse) && CollectionUtils.isNotEmpty(queryCargoZoneByIdResponse.getResult())) {
                Map<String, String> result = (Map<String, String>) queryCargoZoneByIdResponse.getResult().get(0);
                //工厂code
                allocateApplyOrderDetailDTO.setFactoryCode(result.get(SAP_FACTORY_CODE));
                //库存code
                allocateApplyOrderDetailDTO.setStockCode(result.get(WAREHOUSE_CODE));
                //发货仓名称
                allocateApplyOrderDetailDTO.setShipWarehouseName(result.get(NAME));
                allocateApplyOrderDetailDTO.setShipWarehouseCode(result.get("code"));
            }
        }
        //地址信息
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getCustomerAddressId())) {
            BatchQueryByIdsRequest batchQueryByIdsRequest = new BatchQueryByIdsRequest();
            batchQueryByIdsRequest.setIdList(Lists.newArrayList(allocateApplyOrderDetailDTO.getCustomerAddressId()));
            Result<List<CustomerAddress>> listResult = customerAddressService.batchQueryByIds(batchQueryByIdsRequest);
            if (Objects.nonNull(listResult) && CollectionUtils.isNotEmpty(listResult.getResult())) {
                List<CustomerAddress> addressList = listResult.getResult();
//                String addressCode = addressList.get(0).getAddressCode();

                for (CustomerAddress customerAddress : addressList) {
                    allocateApplyOrderDetailDTO.setAddress(customerAddress.getAddress());
                    allocateApplyOrderDetailDTO.setAddressName(customerAddress.getAddressName());
                    allocateApplyOrderDetailDTO.setCustomerCode(customerAddress.getCustomerCode());
                    if (StringUtils.isNotEmpty(customerAddress.getCustomerCode())) {
                        BatchQueryCustomersRequest batchQueryCustomersRequest = new BatchQueryCustomersRequest();
                        batchQueryCustomersRequest.setCodes(Lists.newArrayList(customerAddress.getCustomerCode()));
                        Object o = otsPlatformEnhanceService.batchQueryCustomers(batchQueryCustomersRequest);
                        if (Objects.nonNull(o)) {
                            JSONObject data = JSONObject.parseObject(JSON.toJSONString(o));
                            if (Objects.nonNull(data)) {
                                JSONArray res = data.getJSONArray("result");
                                if (Objects.nonNull(res) && res.size() > 0) {
                                    JSONObject jsonObject = res.getJSONObject(0);
                                    if (Objects.nonNull(jsonObject)) {
                                        allocateApplyOrderDetailDTO.setCustomerName(jsonObject.get("name").toString());
                                    }
                                }
                            }
                        }
                    }
                }
//                //放入客户信息
//                AllocateOrderGetCustomerResponse customer = InfoUtil.getCustomerByAddressCode(addressCode);
//                if (customer != null){
////                    allocateApplyOrderDetailDTO.setAddressName(customer.getCustomerAddressName());
////                    allocateApplyOrderDetailDTO.setCustomerName(customer.getCustomerName());
////                    allocateApplyOrderDetailDTO.setAddress(customer.getCustomerAddress());
//                    if (StringUtils.isNotBlank(customer.getCustomerName())){
//                        allocateApplyOrderDetailDTO.setCustomer(customer.getCustomerName());
//                    }else {
//                        allocateApplyOrderDetailDTO.setCustomer(allocateApplyOrderDetailDTO.getCustomerName());
//                    }
//                    allocateApplyOrderDetailDTO.setCustomerAddress(customer.getCustomerAddress());
//                    allocateApplyOrderDetailDTO.setCustomerAddressName(customer.getCustomerAddressName());
//                }
            }
        }

        //code转名称
        //调拨类型
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getType())) {
            allocateApplyOrderDetailDTO.setTypeName(
                    EnumUtils.getAllocateOrderTypeByCode(Integer.valueOf(allocateApplyOrderDetailDTO.getType())).getDesc());
        }
        //创建人名称
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getCreator())) {
            if ("0".equals(allocateApplyOrderDetailDTO.getCreator())){
                allocateApplyOrderDetailDTO.setCreatorId(allocateApplyOrderDetailDTO.getCreator());
                allocateApplyOrderDetailDTO.setCreator("系统");
            }else{
                JSONObject obj = JSON.parseObject(allocateApplyOrderDetailDTO.getCreator());
                allocateApplyOrderDetailDTO.setCreatorId(allocateApplyOrderDetailDTO.getCreator());
                allocateApplyOrderDetailDTO.setCreator(obj.getString(REAL_NAME));
                if (StringUtils.isNotBlank(obj.getString(REAL_NAME))) {
                    if ("unknown".equals(obj.getString(REAL_NAME)) || "bot_sap".equals(obj.getString(REAL_NAME)) || "0".equals(obj.getString(REAL_NAME))) {
                        allocateApplyOrderDetailDTO.setCreator("系统");
                    }
                }
            }
        }
        //单据原因名称
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getDocumentReason())) {
            allocateApplyOrderDetailDTO.setDocumentReasonName(EnumUtils.getDocumentReasonByCode(allocateApplyOrderDetailDTO.getDocumentReason()).getDesc());
        }
        //运输方式 下游存储问题需要转换数据
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getShipMethod())) {
            String shipMethod = allocateApplyOrderDetailDTO.getShipMethod();
            if (1 == shipMethod.length()) {
                shipMethod = ZERO_STRING + shipMethod;
            }
            allocateApplyOrderDetailDTO.setShipMethod(shipMethod);
            allocateApplyOrderDetailDTO.setShipMethodName(EnumUtils.getTransportModeByCode(shipMethod).getDesc());
        }
        //是否直发客户
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getIsDTC())) {
            allocateApplyOrderDetailDTO.setIsDTCName(allocateApplyOrderDetailDTO.getIsDTC() ? YES_NAME : NO_NAME);
        } else {
            allocateApplyOrderDetailDTO.setIsDTCName(NO_NAME);
        }
        if (StringUtils.isNotEmpty(allocateApplyOrderDetailDTO.getSapCallbackMessage()) && AllocateApplyOrderStatusEnum.TO_BE_SUBMITTED.getCode().equals(allocateApplyOrderDetailDTO.getStatus())) {
            allocateApplyOrderDetailDTO.setMessage(allocateApplyOrderDetailDTO.getSapCallbackMessage());
        }
        //提报组织
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getApplyOrg())) {
            BaselineGetOrganizationByIdsRequest baselineGetOrganizationByIdsRequest = new BaselineGetOrganizationByIdsRequest();
            baselineGetOrganizationByIdsRequest.setIds(Lists.newArrayList(allocateApplyOrderDetailDTO.getApplyOrg().toString()));
            Map baselineGetOrganizationByIdsMap = (Map) baseDataService.baselineGetOrganizationByIds(baselineGetOrganizationByIdsRequest);
            Map<String, String> organizationMap = new HashMap<>();
            if (Objects.nonNull(baselineGetOrganizationByIdsMap)) {
                List<Map> organization = (List<Map>) baselineGetOrganizationByIdsMap.get(RESULT);
                if (Objects.nonNull(organization)) {
                    for (Map map : organization) {
                        if (Objects.nonNull(map.get(ORGANIZATION_SDO))) {
                            Map organizationSDO = (Map) map.get(ORGANIZATION_SDO);
                            if (Objects.nonNull(organizationSDO.get(ID)) && Objects.nonNull(organizationSDO.get(NAME))) {
                                organizationMap.put(organizationSDO.get(ID).toString(), organizationSDO.get(NAME).toString());
                            }
                        }

                    }
                }
                allocateApplyOrderDetailDTO.setApplyOrgName(organizationMap.get(allocateApplyOrderDetailDTO.getApplyOrg().toString()));
            }
        }

        //分公司客户名称
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getBranchCustomersCode())) {
//            AllocateOrderGetCustomerResponse customerInfo = InfoUtil.getCustomer(allocateApplyOrderDetailDTO.getBranchCustomersCode());
//            if (Objects.nonNull(customerInfo)){
//                allocateApplyOrderDetailDTO.setBranchCustomersName(customerInfo.getCustomerName());
//            }

            //上面的有权限
            Map<String, AllocateOrderGetCustomerResponse> customerMap = InfoUtil.getCustomerMap(Lists.newArrayList(allocateApplyOrderDetailDTO.getBranchCustomersCode()));
            if (customerMap != null) {
                AllocateOrderGetCustomerResponse customerResponse = customerMap.get(allocateApplyOrderDetailDTO.getBranchCustomersCode());
                if (customerResponse != null) {
                    allocateApplyOrderDetailDTO.setBranchCustomersName(customerResponse.getCustomerName());
                }
            }
        }
        //详情
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getList())) {
            for (AllocateApplyOrderGoodsDetailDTO allocateApplyOrderGoodsDetailDTO : allocateApplyOrderDetailDTO.getList()) {
                //提报数量
                Integer applyQuantity = allocateApplyOrderGoodsDetailDTO.getApplyQuantity();
                //回复数量
                Integer replyQuantity = allocateApplyOrderGoodsDetailDTO.getReplyQuantity();
                //差量
                if (Objects.nonNull(applyQuantity) && Objects.nonNull(replyQuantity)) {
                    allocateApplyOrderGoodsDetailDTO.setDifferenceQuantity(applyQuantity - replyQuantity);
                }
                //拒绝原因
                if (Objects.nonNull(allocateApplyOrderGoodsDetailDTO.getCloseReason())) {
                    ReasonForRejectionEnum reasonForRejectionByCode = EnumUtils.getReasonForRejectionByCode(allocateApplyOrderGoodsDetailDTO.getCloseReason());
                    if (Objects.nonNull(reasonForRejectionByCode)) {
                        allocateApplyOrderGoodsDetailDTO.setCloseReasonDescribe(reasonForRejectionByCode.getDesc());
                    } else {
                        allocateApplyOrderGoodsDetailDTO.setCloseReasonDescribe(NULL_STRING);
                    }
                }
                //发货仓库
                allocateApplyOrderGoodsDetailDTO.setReceiveWarehouseName(allocateApplyOrderDetailDTO.getReceiveWarehouseName());
                //行状态名称
                if (Objects.nonNull(allocateApplyOrderGoodsDetailDTO.getStatus())) {
                    allocateApplyOrderGoodsDetailDTO.setStatusName(EnumUtils.getAllocateApplyOrderStatusEnum(allocateApplyOrderGoodsDetailDTO.getStatus()));
                } else {
                    allocateApplyOrderGoodsDetailDTO.setStatusName(EnumUtils.getAllocateApplyOrderStatusEnum(allocateApplyOrderDetailDTO.getStatus()));
                }
                if (Objects.nonNull(allocateApplyOrderGoodsDetailDTO.getReturnGood())) {
                    allocateApplyOrderGoodsDetailDTO.setReturnGoodName(ZERO_STRING.equals(allocateApplyOrderGoodsDetailDTO.getReturnGood()) ? NO_NAME : YES_NAME);
                } else {
                    allocateApplyOrderGoodsDetailDTO.setReturnGoodName(NO_NAME);
                }

                //折扣 (单价×数量-小计金额（折后金额，小计金额等于空，就取单价×数量）)
                if (Objects.nonNull(allocateApplyOrderGoodsDetailDTO.getUnitPrice()) && Objects.nonNull(allocateApplyOrderGoodsDetailDTO.getApplyQuantity())) {
//                    单价*提报数量 – 小计金额
                    BigDecimal discount = allocateApplyOrderGoodsDetailDTO.getUnitPrice().multiply(new BigDecimal(allocateApplyOrderGoodsDetailDTO.getApplyQuantity()));
                    //小计金额 = 折后金额
                    if (Objects.isNull(allocateApplyOrderGoodsDetailDTO.getSubtotalMoney())) {
                        allocateApplyOrderGoodsDetailDTO.setSubtotalMoney(discount);
                    }
                    if (Objects.nonNull(allocateApplyOrderGoodsDetailDTO.getSubtotalMoney())) {
                        allocateApplyOrderGoodsDetailDTO.setDiscount(discount.subtract(allocateApplyOrderGoodsDetailDTO.getSubtotalMoney()));
                    } else {
                        allocateApplyOrderGoodsDetailDTO.setDiscount(discount);
                    }
                }
            }
        }
        //@TODO 货品组 这里值定死，有接口在换值 万文洋
        allocateApplyOrderDetailDTO.setGoodsGroupName("常温");
        //新增 财务信息 详情页查询单据保存数据，编辑页详情实时查询信贷报表的数据(草稿/待推送)
        //0629 只有总部销售调拨预报单需要显示客户可发货余额和可下预报单金额,其他的去除显示
        if (Objects.equals(allocateApplyOrderDetailDTO.getType(), AllocateOrderTypeEnum.HEADQUARTER_SALES.getType().toString())){
            if (StringUtils.isNotBlank(allocateApplyOrderDetailDTO.getApplyOrg()) &&
                    (AllocateApplyOrderStatusEnum.DRAFT.getCode().equals(allocateApplyOrderDetailDTO.getStatus())
                            || AllocateApplyOrderStatusEnum.TO_BE_SUBMITTED.getCode().equals(allocateApplyOrderDetailDTO.getStatus()))){
                CreditLoadListRequest creditLoadListRequest = new CreditLoadListRequest();
                creditLoadListRequest.setCompanyId(allocateApplyOrderDetailDTO.getApplyOrg());
                Result<List<Credit>> creditResult = creditService.loadList(creditLoadListRequest);
                if (creditResult != null && CollectionUtils.isNotEmpty(creditResult.getResult())){
                    //客户可发货余额
                    allocateApplyOrderDetailDTO.setCustomerActualAvailableAmount(creditResult.getResult().get(0).getCustomerActualAvailableAmount());
                    //可下预报订单金额
                    allocateApplyOrderDetailDTO.setAllowPlacedOrderAmount(creditResult.getResult().get(0).getAllowPlacedOrderAmount());
                }
            }
        }else {
            allocateApplyOrderDetailDTO.setCustomerActualAvailableAmount(null);
            allocateApplyOrderDetailDTO.setAllowPlacedOrderAmount(null);
        }


        return allocateApplyOrderDetailDTO;
    }

    public static List<CustomerAndAddressInfo> getCustomerAndAddressInfo(List<String> ids) {
        List<CustomerAndAddressInfo> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(ids)) {
            BatchQueryByIdsRequest batchQueryByIdsRequest = new BatchQueryByIdsRequest();
            batchQueryByIdsRequest.setIdList(ids);
            Result<List<CustomerAddress>> listResult = customerAddressService.batchQueryByIds(batchQueryByIdsRequest);
            if (Objects.nonNull(listResult) && CollectionUtils.isNotEmpty(listResult.getResult())) {
                List<CustomerAddress> addressList = listResult.getResult();
                for (CustomerAddress customerAddress : addressList) {
                    CustomerAndAddressInfo customerAndAddressInfo = new CustomerAndAddressInfo();
                    customerAndAddressInfo.setAddress(customerAddress.getAddress());
                    customerAndAddressInfo.setAddressName(customerAddress.getAddressName());
                    customerAndAddressInfo.setCustomerCode(customerAddress.getCustomerCode());
                    customerAndAddressInfo.setCustomerAddressId(null == customerAddress.getId()?null:customerAddress.getId().toString());
                    customerAndAddressInfo.setCustomerAddressCode(customerAddress.getAddressCode());
                    if (StringUtils.isNotEmpty(customerAddress.getCustomerCode())) {
                        BatchQueryCustomersRequest batchQueryCustomersRequest = new BatchQueryCustomersRequest();
                        batchQueryCustomersRequest.setCodes(Lists.newArrayList(customerAddress.getCustomerCode()));
                        Object o = otsPlatformEnhanceService.batchQueryCustomers(batchQueryCustomersRequest);
                        if (Objects.nonNull(o)) {
                            JSONObject data = JSONObject.parseObject(JSON.toJSONString(o));
                            if (Objects.nonNull(data)) {
                                JSONArray res = data.getJSONArray("result");
                                if (Objects.nonNull(res) && res.size() > 0) {
                                    JSONObject jsonObject = res.getJSONObject(0);
                                    if (Objects.nonNull(jsonObject)) {
                                        customerAndAddressInfo.setCustomerName(jsonObject.get("name").toString());
                                    }
                                }
                            }
                        }
                    }
                    list.add(customerAndAddressInfo);
                }
            }
        }
        return list;
    }

    @Autowired
    public void setUnifiedInventoryService(UnifiedInventoryService unifiedInventoryService) {
        AllocateApplyOrdeUtils.unifiedInventoryService = unifiedInventoryService;
    }

    @Autowired
    public void setCrPlatformEnhanceService(CrPlatformEnhanceService otsPlatformEnhanceService) {
        AllocateApplyOrdeUtils.otsPlatformEnhanceService = otsPlatformEnhanceService;
    }

    @Autowired
    public void setBaseDataService(BaseDataService baseDataService) {
        AllocateApplyOrdeUtils.baseDataService = baseDataService;
    }

    @Autowired
    public void setCustomerAddressService(CustomerAddressService customerAddressService) {
        AllocateApplyOrdeUtils.customerAddressService = customerAddressService;
    }

    @Autowired
    public void setCreditService(CreditService creditService) {
        AllocateApplyOrdeUtils.creditService = creditService;
    }
}
